package com.wondertek.onvif.service.auth;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.HttpURLConnection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 认证管理器
 * 负责管理和选择合适的认证策略
 */
@Slf4j
@Component
public class AuthenticationManager {
    
    private static final Logger log = LoggerFactory.getLogger(AuthenticationManager.class);
    
    private final List<AuthenticationStrategy> strategies;
    
    @Autowired
    public AuthenticationManager(List<AuthenticationStrategy> strategies) {
        // 按优先级排序
        this.strategies = strategies.stream()
                .sorted((a, b) -> Integer.compare(a.getPriority(), b.getPriority()))
                .collect(Collectors.toList());
        
        log.info("已加载认证策略: {}", 
                this.strategies.stream()
                        .map(s -> s.getAuthType() + "(优先级:" + s.getPriority() + ")")
                        .collect(Collectors.joining(", ")));
        
        // 验证是否包含WS-Security认证策略
        boolean hasWsSecurityStrategy = strategies.stream()
            .anyMatch(s -> "WS-Security".equals(s.getAuthType()));
        if (hasWsSecurityStrategy) {
            log.info("已检测到WS-Security认证策略，符合ONVIF标准");
        }
    }
    
    /**
     * 获取所有可用的认证策略（按优先级排序）
     * 
     * @return 认证策略列表
     */
    public List<AuthenticationStrategy> getStrategies() {
        return strategies;
    }
    
    /**
     * 根据HTTP连接响应选择合适的认证策略
     * 
     * @param connection HTTP连接
     * @return 支持的认证策略列表
     */
    public List<AuthenticationStrategy> getSupportedStrategies(HttpURLConnection connection) {
        return strategies.stream()
                .filter(strategy -> strategy.isSupported(connection))
                .collect(Collectors.toList());
    }
    
    /**
     * 获取指定类型的认证策略
     * 
     * @param authType 认证类型
     * @return 认证策略，如果不存在则返回null
     */
    public AuthenticationStrategy getStrategy(String authType) {
        return strategies.stream()
                .filter(strategy -> strategy.getAuthType().equalsIgnoreCase(authType))
                .findFirst()
                .orElse(null);
    }
    
    /**
     * 尝试使用所有可用策略进行认证
     * 
     * @param username 用户名
     * @param password 密码
     * @param serviceUrl 服务URL
     * @param method HTTP方法
     * @return 第一个成功的认证头，如果都失败则返回null
     */
    public String tryAuthenticate(String username, String password, String serviceUrl, String method) {
        for (AuthenticationStrategy strategy : strategies) {
            try {
                String authHeader = strategy.buildAuthHeader(username, password, serviceUrl, method);
                if (authHeader != null) {
                    log.debug("使用{}认证策略成功构建认证头", strategy.getAuthType());
                    return authHeader;
                }
            } catch (Exception e) {
                log.warn("{}认证策略失败: {}", strategy.getAuthType(), e.getMessage());
            }
        }
        
        log.warn("所有认证策略都失败了");
        return null;
    }
}